« powrót

Kontrola danych w formularzu

Opublikowano: 2009-07-28 , wyświetlono: 8061


Prawie każdy wypełniał jakiś formularz na stronie www. Klikamy na przycisk Submit i czekamy na komunikat o poprawności przesłanych danych. Czekamy ... , a tu niespodzianka okazało się, że błędnie podaliśmy jakąś informacje i sktypt poinformował nas o błędzie we wprowadzonych danych. Wracamy na poprzednią stronę, uzupełniamy to co trzeba i już z pewną nieśmiałością czekamy na odpowiedź serwera.

Ten sam ból mają twórcy skryptów, np. w jakim formacie użytkownik wprowadzi datę, może rrrr/mm/dd, a może dd/mm/rr.

Mając na uwadze te problemy, które wynikły w mojej praktyce stworzyłem klasę JavaScript do kontroli danych wprowadzonych w formularzu.

Załóżmy, że na stronie www mam zdefiniowany następujący formularz

Wiek:
Identyfikator:
Data [dd/mm/rrrr]:
 
którego kod wygląda następująco:


<FORM  NAME="form1">

Wiek:  <INPUT  TYPE="text"  NAME="nazwa1"  VALUE="0">
Identyfikator:  <INPUT  TYPE="text"  NAME="nazwa2">
Data  [dd/mm/rrrr]:  <INPUT  TYPE="text"  NAME="nazwa3">
<INPUT  TYPE="submit"  NAME="ok"  VALUE="Wyślij">

</FORM> 

Moim celem byłoby wprowadzenie przez użytkownika w pola następujących wartości:
wiek - liczba maksymalnie 3 cyfrowa
identyfikator - alfanumeryk nie dłuszy niż 12 znaków
data - w formacie podanym w []
By zyskać większą pewność, że tak będzie spróbuję kontrolować wprowadzone dane. Do tego celu wykorzystam zdarzenie onSubmit obiektu form i do mojego formularza dodam odpowiedni kod, czyli:


<FORM  NAME="form1"  onSubmit="return  Validate();">  

co spowoduje wywołanie funkcji Validate po naciśnięciu przycisku Wyślij. Jak widać funkcja Validate coś powinna zwracać. Może to być wartość true, czyli jeżeli formularz zawiera ACTION to wywoływany jest odpowiedni skrypt lub false i wtedy pozostajemy na stronie z fromularzem i nie wykona się żadna akcja.
Następnym krokiem powinno być utworzenie w JS funkcji Validate, która kontroluje pola i w zależności od ich poprawności zwraca true lub wyświetla komunikat o nieprawidłowościach w danych i zwraca false.

W celu uproszczenia i zuniwersalizowania tego procesu stworzyłem klasę TValidation, która zawiera kilka metod do kontroli danych oraz pozwala na bardzo eleganckie rozwiązanie tego problemu. Dla mojego formularza należałoby dodać następujący kod JS


<script  language="JavaScript"  src="tvalidation.js">
</script>

<script>
function  Validate()
{
    var  v  =  new  TValidation("form1");

    v.AddItem("nazwa1",  "Wiek  musi  byc  wartością  liczbową  o  max  .  długości  3  znaków",  "vLength(v,  3)  &&  Integer(v)");
    v.AddItem("nazwa2",  "Pole  musi  być  wypełnione  i  nie  może  być  dłuższe  niż  12  znaków", "vLength(v,  12)  &&  vRequired(v)");
    v.AddItem("nazwa3",  "Data  musi  być  w  formacie  dd/mm/rrrr",  "vDate(v)");
    return  v.Check();
}
</script> 

Jak widać kod jest dość krótki i w miarę przejrzysty. Wszystkie czynności związane z kontrolą danych spoczywają na obiekcie v, który tworzę na bazie klasy TValidate podając NAME formularza, dla którego ma być wykonana kontrola.
Pola, które mają być sprawdzane specyfikujemy wywołując metodę AddItem z odpowiednimi parametrami. Weryfikacja poprawności pod względem podanych w AddItem warunków dokonuje się w metodzie Check. Jeżeli wszystko jest w porządku to zwracana jest wartość true, w przeciwnym wypadku wyświetla odpowiedni komunikat i zwraca false.
Teraz czas bliżej przyjrzeć się metodzie AddItem. Posiada ona następującą składnię:


AddItem(nazwa_pola,  komunikat_w_wypadku_bledu,  regula_poprawnosci) 

Każdy z parametrów jest typu znakowego. Pierwsze dwa są na tyle jasne, że nie będę ich szczegółowo komentował. Dokładnie zajmę się trzecim parametrem. Jak widać na przykładzie ten parametr składa się z jednej lub wielu funkcji połączonych znakiem &&. Każda funkcja wywoływan jest ze zmienną wskazującą obiekt typu TValidate oraz opcjonalnie z innymi parametrami.
A oto lista możliwych do użycia funkcji kontroli:


vLength(val, nLen)

Funkcja sprawdza, czy długość pola nie jest większa niż nLen.


vRequired(val)

Funkcja sprawdza, czy dane pole nie jest puste.


vIsInteger(val)

Sprawdzenie, czy wartość pola jest liczbą typu całkowitego.


vIsFloat(val)

Sprawdzenie, czy wartość pola jest liczbą typu rzeczywistego.


vDate(val, nFormat)

Funkcja kontroluje czy podany ciag znaków jest poprawną datą, można użyć trzech formatów zależnie od parametru nFormat: 0 - dd/mm/rrrr, 1 - mm/dd/rrrr, 2 - rrrr/mm/dd

Oczywiście klasę można rozbudowywać dodając np. nowe funkcje kontroli. Na pewno stanowi ona niezły wzorzec do dalszych własnych prac.
Kod źrodłowy znajduje się poniżej.


////////////
//
//  Validation  Library
//
//  (c)  Jacek  Murawski,  Kozienice  1999
//
//  e-mail:  jacek.murawski@elko.com.pl
//  http://  www.chinasoft.com.pl
//
////////////

//  funkcje  sprawdzania  poprawnosci  danych  nie  nalezaca  do
//  zadnej  klasy

//  Dostepne  funkcje:
//
//  vLength(val,  nLen)
//  vRequired(val)
//  vIsInteger(val)
//  vIsFloat(val)
//  vDate(val,  nFormat)
//      0  -  dd/mm/rrrr
//      1  -  mm/dd/rrrr
//      2  -  rrrr/mm/dd
//
//  Do  zrobienia:
//
//  vEmail(val)
//  vRangeInt(val,  nFrom,  nTo)
//  vRangeFloat(val,  nFrom,  nTo)
//

//  funkcja  sprawdzajaca,  czy  wartosc  pola  nie  jest  dluzsza  niz  ...
function  vLength(val,  nLen)
{
    if  (val.length  >  nLen)
        return  false;
    else
        return  true;
}

//  funkcja  sprawdza,  czy  wartosc  pola  >  0
function  vRequired(val)
{
    if  (val.length  <  1)
        return  false;
    else
        return  true;
}

//  sprawdzenie  czy  w  polu  liczba  Integer
function  vInteger(val)
{
    var  i  =  0;
    var  is_ok  =  true;
    var  number  =  "+-0123456789";

    if  (number.indexOf(val.charAt(0))  ==  -1)
        is_ok  =  false;

    number  =  number.substring(2,  20);

    for  (i  =  1;  i  <  val.length;  i++)
    {
        if  (number.indexOf(val.charAt(i))  ==  -1)
            is_ok  =  false;
    }

    return  is_ok
}

//  sprawdzenie,  czy  w  polu  liczba  float
function  vFloat(val)
{
    var  i  =  0;
    var  is_ok  =  true;
    var  number  =  "+-0123456789.";

    if  (number.indexOf(val.charAt(0))  ==  -1)
        is_ok  =  false;

    number  =  number.substring(2,  20);

    for  (i  =  1;  i  <  val.length;  i++)
    {
        if  (number.indexOf(val.charAt(i))  ==  -1)
            is_ok  =  false;
    }
    return  is_ok;
}

//  sprawdzenie  czy  w  polu  prawidlowa  data
//      0  -  dd/mm/rrrr
//      1  -  mm/dd/rrrr
//      2  -  rrrr/mm/dd
//              1234567890
function  vDate(val,  format)
{
    var  i  =  0;
    var  is_ok  =  true;
    var  number  =  "0123456789";
    var  s;


    if  (format  ==  null)
        format  =  0;

    //  sprawdzenie  dlugosci
    if  (val.length  !=  10)
        return  false;

    if  (format  ==  0)
    {
        s_month  =  val.substring(0,2);
        s_day  =  val.substring(3,5);
        s_year  =  val.substring(6,10);
        //  separatory
        if  ((val.charAt(2)  !=  "/")  ||  (val.charAt(5)  !=  "/"))
            return  false;
    }

    //  dni
    for  (i  =  0;  i  <  2;  i++)
    {
        if  (number.indexOf(s_day.charAt(i))  ==  -1)
            is_ok  =  false;
    }
    if  (is_ok)
        nDay  =  parseInt(s_day);
    else
        return  false;

    //  miesiace
    for  (i  =  0;  i  <  2;  i++)
    {
        if  (number.indexOf(s_month.charAt(i))  ==  -1)
            is_ok  =  false;
    }
    if  (is_ok)
        nMonth  =  parseInt(s_month);
    else
        return  false;

    //  lata
    for  (i  =  0;  i  <  4;  i++)
    {
        if  (number.indexOf(s_year.charAt(i))  ==  -1)
            is_ok  =  false;
    }

    if  (is_ok)
        nYear  =  parseInt(s_year);
    else
        return  false;

    return  is_ok
}

//////////////////////////////////////////////////////
//
//  definicja  klasy  TValidation
//
//////////////////////////////////////////////////////


//////////////////  Klasa  TField  /////////////////////

function  TField()
{
    this.Name  =  "";
    this.Message  =  "";
    this.isValid  =  false;
    this.Code  =  "";

    this.SetName  =  TField_SetName;
    this.SetMessage  =  TField_SetMessage;
    this.SetIsValid  =  TField_SetIsValid;
    this.SetCode  =  TField_SetCode;

    this.GetName  =  TField_GetName;
    this.GetMessage  =  TField_GetMessage;
    this.GetIsValid  =  TField_GetIsValid;
    this.GetCode  =  TField_GetCode;

    //  sprawdzanie  poprawnosci  pola
    this.Check  =  TField_Check;
}

function  TField_SetName(cName)
{
    this.Name  =  cName;
}
function  TField_SetMessage(cMessage)
{
    this.Message  =  cMessage;
}
function  TField_SetIsValid(bIsValid)
{
    this.isValid  =  bIsValid;
}
function  TField_SetCode(cCode)
{
    return  this.Code  =  cCode;
}


function  TField_GetName()
{
    return  this.Name;
}
function  TField_GetMessage()
{
    return  this.Message;
}
function  TField_GetIsValid()
{
    return  this.isValid;
}
function  TField_GetCode()
{
    return  this.Code;
}


//  sprawdzanie  poprawnosci  pola
function  TField_Check(cForm)
{
    var  v  =  eval("document."  +  cForm  +  "."  +  this.Name  +  ".value");
    this.isValid  =  eval(this.Code);

    //  ewentualna  zmiana  zawartosci  pola
    //    if  (!this.isValid)
    //  {
    //    cNew  =  v  +  "???";
    //    eval("document."  +  cForm  +  "."  +  this.Name  +  ".value  =  "  +  "\""+cNew+"\"");
    //  }
}

///////////////////  Klasa  TListField  ////////////////////

function  TListField()
{
    this.List  =  new  Array(1);
    this.Counter  =  0;

    this.Add  =  TListField_Add;
    this.GetMsg  =  TListField_GetMsg;
    this.IsValid  =  TListField_IsValid;
    this.Check  =  TListField_Check;
    this.Clear  =  TListField_Clear;
    this.BuildMsg  =  TListField_BuildMsg;
}

//  dodanie  wiersz  do  listy  pol
function  TListField_Add(cName,  cMsg,  cCode)
{
    var  fld  =  new  TField;

    fld.SetName(cName);
    fld.SetMessage(cMsg);
    fld.SetIsValid(false);
    fld.SetCode(cCode);

    this.List[this.Counter]  =  fld;
    this.Counter++;
}

//  czyszczenie  listy
function  TListField_Clear()
{
    this.Counter  =  0;
}

//  pobranie  komunikatu
function  TListField_GetMsg(nRow)
{
    var  fld  =  new  TField;

    fld  =  this.List[nRow];
    return  fld.GetMessage();
}

function  TListField_IsValid(nRow)
{
    var  fld  =  new  TField;

    fld  =  this.List[nRow];
    return  fld.GetIsValid();
}

//  sprawdzenie  listy  pol
function  TListField_Check(cForm)
{
    var  fld  =  new  TField;
    var  isOk  =  true;

    for  (i  =  0;  i  <  this.Counter;  i++)
    {
        fld  =  this.List[i];
        fld.Check(cForm);
        this.List[i]  =  fld;
        if  (!fld.GetIsValid())
            isOk  =  false;

    }
    return  isOk;
}

//  budowanie  komunikatu  bledu
function  TListField_BuildMsg()
{
    var  fld  =  new  TField;
    var  cMsg  =  ""

    for  (i  =  0;  i  <  this.Counter;  i++)
    {
        fld  =  this.List[i];
        if  (!fld.GetIsValid())
        {
            cMsg  =  cMsg  +  fld.GetMessage()  +  "\n";
            //  window.alert(cMsg);
        }
    }
    return  cMsg;
}

///////////////////////  klasa  TValidation  ////////////////////

function  TValidation(cForm)
{
    this.FormName  =  cForm;
    this.List  =  new  TListField();

    this.AddItem  =  TValidation_AddItem;
    this.Check  =  TValidation_Check;
    this.MessageWin  =  TValidation_MessageWin;
}

//  dodanie  elementu
function  TValidation_AddItem(cName,  cMsg,  cCode)
{
    this.List.Add(cName,  cMsg,  cCode);
}

//  sprawdzenie  formularza
function  TValidation_Check()
{
    if  (this.List.Check(this.FormName))
        return  true;
    else
    {
        this.MessageWin();
        return  false;
    }
}

//  jezeli  weryfikacja  niepoprawna  to
//  wyswietlenie  okna  z  komunikatem  bledu
function  TValidation_MessageWin()
{
    cMsg  =  "Dane  niepoprawne:\n";
    cMsg2  =  this.List.BuildMsg();

    window.alert(cMsg+cMsg2);
} 


Komentarze: